package com.yixq.soa.service.comm.utils;

import com.google.common.base.Joiner;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class HTTPUtils {
	public static String DEFAULT_CHARSET = "utf-8";
	public static String ACCEPT_HEAD = "text/plain, text/plain, application/json, application/json, application/*+json, application/*+json, */*, */*";
	private static Logger log = LoggerFactory.getLogger(HTTPUtils.class);
	
	public static String get(String urlWhitParam) throws Exception{
		return get(urlWhitParam,DEFAULT_CHARSET);
	}

	public static String get(String urlWhitParam,String charset) throws Exception {
		log.debug("HTTP GET:" + urlWhitParam);
        StringBuilder result = new StringBuilder();
        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpGet httpGet = new HttpGet(urlWhitParam);
            httpGet.addHeader(new BasicHeader("Accept", ACCEPT_HEAD));
            CloseableHttpResponse response1 = httpClient.execute(httpGet);

            log.debug(response1.getStatusLine().toString());
            HttpEntity entity1 = response1.getEntity();

            BufferedReader br = new BufferedReader(new InputStreamReader(entity1.getContent(), charset));

            String line = br.readLine();
            while (line != null) {
                result.append(line);
                line = br.readLine();
            }
            EntityUtils.consume(entity1);
            return result.toString();
        }
    }

    public static String build_url_for(String url, Map<String, String> parameter) throws UnsupportedEncodingException {
        StringBuilder urlParams = new StringBuilder(url.length() + 50);
		List<String> urlVariables = new ArrayList<>(255);
        try {
            for (Map.Entry<String, String> entry : parameter.entrySet()) {
                String key = entry.getKey();
                String value = URLEncoder.encode(entry.getValue(), DEFAULT_CHARSET);
                urlParams.append(key).append("=").append(value);
                urlVariables.add(urlParams.toString());
                urlParams.delete(0, urlParams.length());
            }
        } catch (Exception ex) {
            //TODO: 异常处理
        }
		urlParams.append(url)
				.append("?")
				.append(Joiner.on("&").join(urlVariables));
		return urlParams.toString();
	}

	public static <T> T get(String url, Class<T> responseType, Map<String, String> parameter) throws Exception {
		String respText = get(build_url_for(url, parameter), DEFAULT_CHARSET);
		MappingJackson2HttpMessageConverter convert = new MappingJackson2HttpMessageConverter();
		T response = (T) convert.read(responseType, new HttpInputMessage() {
			@Override
			public InputStream getBody() throws IOException {
				return new StringBufferInputStream(respText);
			}

			@Override
			public HttpHeaders getHeaders() {
				return null;
			}
		});
		return response;
	}

	public static String post(String urlWhitParam,String body) throws Exception{
		return post(urlWhitParam,body,DEFAULT_CHARSET);
	}
	
	public static String post(String urlWhitParam,String body,String charset) throws Exception{
		log.debug("HTTP POST(Body):" + urlWhitParam);

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(urlWhitParam);
            httpPost.addHeader(new BasicHeader("Accept", ACCEPT_HEAD));

            if (body != null) {
                httpPost.setEntity(new StringEntity(body, charset));
            }

            try (CloseableHttpResponse response1 = httpClient.execute(httpPost)) {
                log.debug(response1.getStatusLine().toString());
                HttpEntity entity1 = response1.getEntity();

                BufferedReader br = new BufferedReader(new InputStreamReader(entity1.getContent(), charset));

                StringBuffer result = new StringBuffer();

                String line = br.readLine();
                while (line != null) {
                    result.append(line);
                    line = br.readLine();
                }

                EntityUtils.consume(entity1);

                return result.toString();
            }
        }
    }
	
	public static String post(String urlWhitParam,Map<String,String> formParam) throws Exception{
		return post(urlWhitParam,formParam,DEFAULT_CHARSET);
	}


    public static String post(String urlWhitParam, Map<String, String> formParam, String charset) throws Exception {
        log.debug("HTTP POST(Form):" + urlWhitParam);

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            HttpPost httpPost = new HttpPost(urlWhitParam);
            httpPost.addHeader(new BasicHeader("Accept", ACCEPT_HEAD));

            List<NameValuePair> nvps = null;
            if (formParam != null && formParam.size() > 0) {
                nvps = new ArrayList<NameValuePair>();
                for (String key : formParam.keySet()) {
                    nvps.add(new BasicNameValuePair(key, formParam.get(key)));
                }
            }

            if (nvps != null) {
                httpPost.setEntity(new UrlEncodedFormEntity(nvps));
            }
            try (CloseableHttpResponse response1 = httpClient.execute(httpPost)) {
                log.debug(response1.getStatusLine().toString());
                HttpEntity entity1 = response1.getEntity();

                BufferedReader br = new BufferedReader(new InputStreamReader(entity1.getContent(), charset));

                StringBuffer result = new StringBuffer();

                String line = br.readLine();
                while (line != null) {
                    result.append(line);
                    line = br.readLine();
                }

                EntityUtils.consume(entity1);

                return result.toString();
            }
        }
    }
}
